<?php
namespace app\sysadmin\controller;
use app\common\controller\Base as Base;
use think\captcha\Captcha;
use think\Db;
class Login extends Base{
	public function __construct(){
		parent::__construct();
		$this->assign('source', $this->_public."sysadmin/");
		$this->view->engine->layout(false);
	}
	public function index(){
		if($this->request->isGet() != true){
			$this->error('404');
		}
		session(null);
		return $this->fetch();
	}
	// 登陆
	public function onlogin(){
		if($this->request->isAjax() != true){
			$this->error('404');
		}
		$_post_data = input('post.');
		if(config('gee_stutas') == 1){
			if(!$this->gee_check($_post_data)){
				$this->error("验证失败，请重试");
			}
		}
		// 过滤无用信息
		if($_post_data){
			foreach($_post_data as $k=>$v){
				if(!in_array($k,array('username','password','code'))){
					unset($_post_data[$k]);
				}else{
					$_post_data[$k] = trim($v);
				}
			}
		}
		$captcha = new Captcha(\Config::pull('captcha'));
        $_ret = $captcha->check($_post_data['code'],'admin_login');
        if(!$_ret){
            $this->error("验证码错误，请重试");
        }
		$_ip = $this->request->ip();
		// 同一个ip 重复 多次失败 封ip 半小时
		$_login_ip = cache('admin_login_'.$_ip);
		if($_login_ip['num'] > 10){
			$this->error("登录过于频繁，请".ceil(($_login_ip['time']+30*60 - time())/60)."分钟以后再试");
		}
		// 同一个账号 重复多次失败 封账户半小时
		$_login_username = cache('admin_login_'.$_post_data['username']);
		if($_login_username['num'] > 5){
			$this->error("登录过于频繁，请".ceil(($_login_ip['time']+30*60 - time())/60)."分钟以后再试");
		}
		
		// 登陆日志
		$_login_log = array(
			'user_name' => $_post_data['username'],
			'user_pass' => $_post_data['password'],
			'login_status' => '0',
			'login_ip' => $_ip,
			'login_url' => $this->request->server('HTTP_REFERER'),
			'login_agent' => $this->request->server('HTTP_USER_AGENT'),
			'login_date' => date('Y-m-d H:i:s'),
		);
		
		$_admin_info = Db::name('Admin')->where('username','=',$_post_data['username'])->field('id,username,password,sign,role_id,status,name')->find();
		if(!$_admin_info){
			$_login_log['login_status'] = 0;
			$this->add_admin_login_log($_login_log);
			$this->log_login_error(['ip'=>$_ip,'username'=>$_post_data['username']]);
			$this->error("账户、密码不正确，请重新输入");
		}
		if($_admin_info['password'] != md5(md5($_post_data['password']).$_admin_info['sign'])){
			$_login_log['login_status'] = 0;
			$this->add_admin_login_log($_login_log);
			$this->log_login_error(['ip'=>$_ip,'username'=>$_post_data['username']]);
			$this->error("账户、密码不正确，请重新输入");
		}
		$this->log_login_error_clear(['ip'=>$_ip,'username'=>$_post_data['username']]);
		if($_admin_info['status'] != 1){
			$_login_log['login_status'] = 0;
			$this->add_admin_login_log($_login_log);
			$this->error("该账户已被冻结，请联系总管理员");
		}
		// 验证 角色
		session('admin_id',$_admin_info['id']);
		session('role_id',$_admin_info['role_id']);
		session('admin_name',$_admin_info['name']?$_admin_info['name']:$_admin_info['username']);
		
		$_login_log['login_status'] = 1;
		$this->add_admin_login_log($_login_log);
		// 登陆成功以后重置失败次数
		$this->success("登陆成功",url('Index/index'));
	}
	// 验证码
	public function verify(){
		if($this->request->isGet() != true){
			$this->error('404');
		}
        $captcha = new Captcha(\Config::pull('captcha'));
        return $captcha->entry('admin_login');
	}
	// 获取 极验证
	public function gee_verify(){
		if($this->request->isAjax() != true){
			$this->error('404');
		}
		$GtSdk = new \app\common\other\GeetestLib(config('app_wy.gee_captcha_id'), config('app_wy.gee_private_key'));
		$data = array(
			"user_id" => "test", # 网站用户id
			"client_type" => "web", #web:电脑上的浏览器；h5:手机上的浏览器，包括移动应用内完全内置的web_view；native：通过原生SDK植入APP应用的方式
			"ip_address" => $this->request->ip()
		);
		$status = $GtSdk->pre_process($data,1);
		session('gtserver',$status);
		session('user_id',$data['user_id']);
		echo $GtSdk->get_response_str();
	}
	// 空操作
	public function _empty(){
		echo '404';exit;
    }
	
	// 验证 极验证
	private function gee_check($_post_data){
		$GtSdk = new \app\common\other\GeetestLib(config('app_wy.gee_captcha_id'), config('app_wy.gee_private_key'));
		$data = array(
			"user_id" => session('user_id'), # 网站用户id
			"client_type" => "web", #web:电脑上的浏览器；h5:手机上的浏览器，包括移动应用内完全内置的web_view；native：通过原生SDK植入APP应用的方式
			"ip_address" => $this->request->ip()
		);


		if (session('gtserver') == 1) {   //服务器正常
			$result = $GtSdk->success_validate($_post_data['geetest_challenge'], $_post_data['geetest_validate'], $_post_data['geetest_seccode'], $data);
			if($result){
				return true;
			}else{
				return false;
			}
		}else{  //服务器宕机,走failback模式
			if($GtSdk->fail_validate($_post_data['geetest_challenge'],$_post_data['geetest_validate'],$_post_data['geetest_seccode'])){
				return true;
			}else{
				return false;
			}
		}
	}
	// 添加登陆日志
	private function add_admin_login_log($_login_log){
		$admin_login_log_type = config('app_wy.admin_login_log_type');
		if($admin_login_log_type == 1){ // 单表存储登陆日志
		
			Db::name('admin_login')->strict(false)->insert($_login_log);
			
		}elseif($admin_login_log_type == 2){ // 按年存储日志
		
			$login_time = strtotime($_login_log['login_date']);
			$_tables_name = config('database.prefix').'admin_login_'.date('Y',$login_time);
			$_sql = 'show tables like "'.$_tables_name.'"';
			
			$is_tables = Db::query($_sql);
			if(!$is_tables){
				// 添加数据库
				$_add_sql = "CREATE TABLE `".$_tables_name."` (
					  `id` int(11) NOT NULL AUTO_INCREMENT,
					  `user_name` varchar(200) NOT NULL COMMENT '用户名',
					  `user_pass` varchar(200) NOT NULL COMMENT '密码',
					  `login_url` varchar(200) NOT NULL COMMENT '登陆地址',
					  `login_ip` varchar(200) NOT NULL COMMENT '登陆ip',
					  `login_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '登陆状态 1 成功 0失败',
					  `login_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '登陆时间',
					  `login_agent` varchar(400) NOT NULL COMMENT '登陆信息',
					  PRIMARY KEY (`id`)
					) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='管理员日志';";
				Db::query($_add_sql);
			}
			$rule = [
				'type' => 'year',
				'expr' => '1',
			];
			Db::name('admin_login')->partition(['login_time' => $login_time], "login_time", $rule)->insert($_login_log);
		}
	}
	
	// 记录错误日志
	private function log_login_error($_data){
		$_cache_ip_name = 'admin_login_'.$_data['ip'];
		$_cache_username_name = 'admin_login_'.$_data['username'];
		$_login_ip = cache($_cache_ip_name);
		$_login_username = cache($_cache_username_name);
		
		if($_login_ip){
			$_login_ip['num'] += 1;
		}else{
			$_login_ip['num'] = 1;
		}
		$_login_ip['time'] = time();
		cache($_cache_ip_name,$_login_ip,1800);
		
		if($_login_username){
			$_login_username['num'] += 1;
		}else{
			$_login_username['num'] = 1;
		}
		$_login_username['time'] = time();
		cache($_cache_username_name,$_login_username,1800);
		
	}
	// 清除错误日志
	private function log_login_error_clear($_data){
		$_cache_ip_name = 'admin_login_'.$_data['ip'];
		$_cache_username_name = 'admin_login_'.$_data['username'];
		cache($_cache_ip_name,null);
		cache($_cache_username_name,null);
	}
}
?>